#include "testbasicinit.h"

#include "system/window.h"
#include "system/windowsmanager.h"
#include "system/windoweventlistener.h"

#include "renderer.h"
#include "renderwindow.h"

#include "inputs/manager.h"
#include "inputs/command.h"

namespace test {
	namespace graffiti {

class BasicInit::WindowListener
:	public dw::system::Window::EventListener
{
public : //! @name Construction & Destruction
	//! @{
	WindowListener(BasicInit* test)
	:	dw::system::Window::EventListener()
	,	m_test(test)
	{
		dwAssert(test != NULL, "Invalid parameter: test is null");
	}
	virtual ~WindowListener() { ; }
	//! @}

public : //! @name dw::system::Window::EventListener Callbacks
	//! @{
	virtual void onClose(dw::system::Window* sender, dw::system::Window::EventArg& eventArg)
	{
		m_test->stop();
	}
	//! @}

private : //! @name Data
	//! @{
	BasicInit* m_test;
	//! @}
};

bool BasicInit::setup()
{
	if (base::setup())
	{
		m_window = new dw::system::Window("test::graffiti", 800, 600, 32, false);
		m_listener = new WindowListener(this);

		m_window->registerListener(m_listener);
		m_window->setTitle("BasicInit");
		m_window->show();

		dw::graffiti::Renderer& renderer = dw::graffiti::Renderer::createInstance();

		m_renderWindow = renderer.initialize(m_window);

		m_exit = new dw::inputs::InputCommand();
		m_exit->addCondition(dw::inputs::KeyStateCondition(OIS::KC_ESCAPE, dw::inputs::ButtonStateCondition::Pressed));

		dw::inputs::InputManager& inputManager = dw::inputs::InputManager::createInstance();
		
		inputManager.initialize(*m_window);
		inputManager.registerCommand(m_exit);

		return true;
	}

	return false;
}

bool BasicInit::run()
{
	bool baseSucceed = base::run();

	m_stop = !baseSucceed;

	while (!m_stop)
	{
		dw::system::WindowsManager::getInstance().handleEvents();
		dw::inputs::InputManager::getInstance().update();

		if (m_exit->isActive())
		{
			stop();
		}

		m_renderWindow->clear();
		m_renderWindow->present();
	}

	return baseSucceed;
}

bool BasicInit::teardown()
{
	dw::inputs::InputManager::getInstance().unregisterCommand(m_exit);
	dw::inputs::InputManager::destroyInstance();

	dw::graffiti::Renderer::destroyInstance();

	m_window->unregisterListener(m_listener);

	delete m_window;
	m_window = NULL;

	delete m_listener;
	m_listener = NULL;

	delete m_renderWindow;
	m_renderWindow = NULL;

	return base::teardown();
}

	} // namespace graffiti
} // namespace test
